package me.illtamer.infinite.file;

import lombok.extern.slf4j.Slf4j;
import me.illtamer.infinite.file.source.FileSource;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

@Slf4j
public class FileType {

    public static final FileType ALL = new FileType("all");

    public static final FileType TXT = new FileType("txt");

    public static final FileType JSON = new FileType("json");

    public static final FileType YAML = new FileType("yaml", "yml");

    public static final FileType UNKNOWN = new FileType("unknown");

    private static final HashMap<String, FileType> expandTypes = new HashMap<>(1 << 4);

    private final String suffix;

    private final List<String> alias;

    private FileType(String suffix, String... alias) {
        this.suffix = suffix;
        this.alias = Arrays.asList(alias);
    }

    /**
     * 获取文件类型名称
     * */
    @NotNull
    public String getSuffix() {
        return suffix;
    }

    /**
     * 获取文件类型别名
     * */
    @NotNull
    public List<String> getAlias() {
        return alias;
    }

    @Override
    public String toString() {
        return "FileType{" +
                "suffix='" + suffix + '\'' +
                ", alias=" + alias +
                '}';
    }

    /**
     * 增加支持转换的文件类型
     * @param suffix 文件后缀名
     * @param alias 文件后缀别名
     * @apiNote {@link FileSource#getType()}
     * */
    public static void addSupportFileType(String suffix, String... alias) {
        if (suffix == null || suffix.length() == 0)
            throw new IllegalArgumentException("Suffix can not be empty !");
        suffix = suffix.toLowerCase(Locale.ROOT);
        FileType put = expandTypes.put(suffix, new FileType(suffix, alias));
        if (put != null)
            log.warn("A FileType is replaced: {}", put);
    }

    @NotNull
    public static FileType getFileType(File file) {
        if (file == null)
            throw new IllegalArgumentException("File can not be null !");
        String name = file.getName();
        return getFileType(name);
    }

    @NotNull
    public static FileType getFileType(String name) {
        if (name == null)
            throw new IllegalArgumentException("File name can not be null !");
        if (!name.contains(".") || name.length() < 2) return UNKNOWN;
        String suffix = name.substring(name.lastIndexOf(".")+1).toLowerCase(Locale.ROOT);
        if (suffix.equals(TXT.suffix) || TXT.alias.contains(suffix))
            return TXT;
        else if (suffix.equals(JSON.suffix) || JSON.alias.contains(suffix))
            return JSON;
        else if (suffix.equals(YAML.suffix) || YAML.alias.contains(suffix))
            return YAML;

        FileType type = expandTypes.get(suffix);
        if (type == null)
            for (FileType fileType : expandTypes.values()) {
                if (fileType.alias.size() == 0) continue;
                if (fileType.alias.contains(suffix)) return fileType;
            }
        return type == null ? UNKNOWN : type;
    }
}
